﻿using Newtonsoft.Json;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using VisionDesigner;
using VM.Common.Enums;
using VM.Common.EventMgrLib;
using VM.Common.Helper;
using VM.Modules.CircleFinding;
using VM.Start.Attributes;
using VM.Start.Common;
using VM.Start.Core;
using VM.Start.Events;
using VM.Start.Models;
using VM.Start.ViewModels;

namespace Plugin.MeasureCircle
{

    [Serializable]
    public enum eLinkCommand
    {
        InputImageLink,
        PositionFix
    }

    [Category("检测识别")]
    [DisplayName("圆形测量")]
    [ModuleImageName("MeasureCircle")]
    [JsonObject(MemberSerialization.OptOut)]
    public class MeasureCircleViewModel : ModuleBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public MeasureCircleViewModel()
        {
            try
            {
                ShowResultCircle = true;
                ShowResultEdgePoint = true;
                ShowResultContour = true;
            }
            catch (MvdException ex)
            {

            }
        }
        #region  属性

        private CircleFinder _circleFinder;
        public CircleFinder circleFinder
        {
            get
            {
                if (_circleFinder == null)
                {
                    _circleFinder = new CircleFinder();
                }
                return _circleFinder;
            }
        }

        #endregion
        #region 数据接口


        private LinkVarModel _InitCenterX = new LinkVarModel() { Text = "10" };

        /// <summary>
        /// 变换前-圆信息
        /// </summary>
        public LinkVarModel InitCenterX
        {
            get { return _InitCenterX; }
            set { _InitCenterX = value; RaisePropertyChanged(); }
        }

        private LinkVarModel _InitCenterY = new LinkVarModel() { Text = "10" };
        /// <summary>
        /// 变换前-圆信息
        /// </summary>
        public LinkVarModel InitCenterY
        {
            get { return _InitCenterY; }
            set { _InitCenterY = value; RaisePropertyChanged(); }
        }

        /// <summary>显示结果直线 </summary>
        private bool _ShowResultCircle = true;
        public bool ShowResultCircle
        {
            get
            {
                return _ShowResultCircle;
            }
            set
            {
                Set(ref _ShowResultCircle, value);
                mWindowH.ShowDrawArc = value;
            }
        }

        /// <summary>显示测量轮廓 </summary>
        private bool _ShowResultContour = true;
        public bool ShowResultContour
        {
            get
            {
                return _ShowResultContour;
            }
            set
            {
                Set(ref _ShowResultContour, value);
                mWindowH.ShowRectangleFList = value;
            }
        }

        /// <summary>显示测量轮廓 </summary>
        private bool _ShowResultEdgePoint = true;
        public bool ShowResultEdgePoint
        {
            get
            {
                return _ShowResultEdgePoint;
            }
            set
            {
                Set(ref _ShowResultEdgePoint, value);
                mWindowH.ShowOutline = value;
            }
        }

        /// <summary>
        /// ROI
        /// </summary>
        public CMvdShape ROI;
        private ROITypeEnum _ROIType = ROITypeEnum.全图;
        public ROITypeEnum ROIType
        {
            get { return _ROIType; }
            set
            {
                Set(ref _ROIType, value, new Action(() =>
                {
                    mWindowH.ROI = ROI;
                    switch (_ROIType)
                    {
                        case ROITypeEnum.全图:
                            mWindowH.ROIType = ROITypeEnum.全图;
                            break;
                        case ROITypeEnum.矩形:
                            mWindowH.ROIType = ROITypeEnum.矩形;
                            break;
                        case ROITypeEnum.圆环:
                            mWindowH.ROIType = ROITypeEnum.圆环;
                            break;
                        default:
                            break;
                    }
                }));
            }
        }

        #endregion
        #region  指令
        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _LinkCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase LinkCommand
        {
            get
            {
                if (_LinkCommand == null)
                {
                    //以GUID+类名作为筛选器
                    EventMgr.Ins.GetEvent<VarChangedEvent>().Subscribe(OnVarChanged, o => o.SendName.StartsWith($"{ModuleGuid}"));
                    _LinkCommand = new CommandBase((obj) =>
                    {
                        eLinkCommand linkCommand = (eLinkCommand)obj;
                        switch (linkCommand)
                        {
                            case eLinkCommand.InputImageLink:
                                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "Image");
                                EventMgr.Ins.GetEvent<OpenVarLinkViewEvent>().Publish($"{ModuleGuid},InputImageLink");
                                break;
                            case eLinkCommand.PositionFix:
                                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "CPositionFixTool");
                                EventMgr.Ins.GetEvent<OpenVarLinkViewEvent>().Publish($"{ModuleGuid},PositionFix");
                                break;
                            default:
                                break;
                        }

                    });
                }
                return _LinkCommand;
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _ExecuteCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase ExecuteCommand
        {
            get
            {
                if (_ExecuteCommand == null)
                {
                    _ExecuteCommand = new CommandBase((obj) =>
                    {
                        ExeModule();
                    });
                }
                return _ExecuteCommand;
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _ConfirmCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase ConfirmCommand
        {
            get
            {
                if (_ConfirmCommand == null)
                {
                    _ConfirmCommand = new CommandBase((obj) =>
                    {
                        var view = this.ModuleView as MeasureCircleView;
                        if (view != null)
                        {
                            view.Close();
                        }
                    });
                }
                return _ConfirmCommand;
            }
        }

        #endregion
        #region  方法
        public override void Loaded()
        {
            base.Loaded();
            var view = ModuleView as MeasureCircleView;
            if (view != null)
            {
                ClosedView = true;
                if (DispImage == null)
                {
                    SetDefaultLink();
                    if (InputImageLinkText == null) return;
                    GetDispImage(InputImageLinkText, true);
                }
            }

        }

        public override void SetDefaultLink()
        {
            if (InputImageLinkText == null)
            {
                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "Image");
                var moduls = VarLinkViewModel.Ins.Modules.LastOrDefault();
                if (moduls?.VarModels.Count > 0)
                {
                    InputImageLinkText = $"&{moduls.DisplayName}.{moduls.VarModels[0].Name}";
                }
            }

            if (PositionFixText == null)
            {
                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "CPositionFixTool");
                var moduls = VarLinkViewModel.Ins.Modules.LastOrDefault();
                if (moduls?.VarModels.Count > 0)
                {
                    PositionFixText = $"&{moduls.DisplayName}.{moduls.VarModels[0].Name}";
                }
            }
        }

        private void OnVarChanged(VarChangedEventParamModel obj)
        {
            switch (obj.SendName.Split(',')[1])
            {
                case "InputImageLink":
                    InputImageLinkText = obj.LinkName;
                    if (InputImageLinkText == null) return;
                    GetDispImage(InputImageLinkText, true);
                    break;
                case "PositionFix":
                    PositionFixText = obj.LinkName;
                    if (PositionFixText == null) return;
                    GetPositionFix(PositionFixText);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 运行模块
        /// </summary>
        /// <returns></returns>
        public override bool ExeModule()
        {
            Stopwatch.Restart();
            try
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    mWindowH.Clear();
                    if (InputImageLinkText != null)
                    {
                        GetDispImage(InputImageLinkText, true);
                    }
                    else
                    {
                        SetDefaultLink();
                    }
                });
                if ((null == circleFinder.CircleFindTool) || (DispImage == null) || DispImage.IsEmpty)
                {
                    ChangeModuleRunStatus(eRunStatus.NG);
                    return false;
                }

                // 算法处理
                circleFinder.InputImage = DispImage;
                if (IsPositionFix && PositionFixTool != null && mWindowH.ROI != null)
                {
                    PositionFixTool.BasicParam.InitialShape = mWindowH.ROI;
                    PositionFixTool.Run();
                    mWindowH.PositionFixROI = PositionFixTool.Result.CorrectedShape;
                    circleFinder.ROI = mWindowH.PositionFixROI;
                }
                else
                {
                    circleFinder.ROI = mWindowH.ROI;
                }
                ROI = mWindowH.ROI;
                bool flag = circleFinder.Run();
                if (flag)
                {
                    ChangeModuleRunStatus(eRunStatus.OK);
                    mWindowH.DrawArc(circleFinder.DrawArc);
                    mWindowH.DrawRectangleFList(circleFinder.RectangleFList);
                    mWindowH.DrawOutline(circleFinder.LineSegmentFList);
                }
                else
                {
                    ChangeModuleRunStatus(eRunStatus.NG);
                }
                return flag;
            }
            catch
            {
                ChangeModuleRunStatus(eRunStatus.NG);
                return false;
            }
        }

        public override bool ExeModule(string TemplateName)
        {
            return ExeModule();
        }

        /// <summary>
        /// 添加结果
        /// </summary>
        public override void AddOutputParams()
        {
            AddOutputParam("圆心X", "double", circleFinder.Result.CenterX);
            AddOutputParam("圆心Y", "double", circleFinder.Result.CenterY);
            AddOutputParam("半径", "double", circleFinder.Result.Radius);
            AddOutputParam("直径", "double", circleFinder.Result.Radius * 2);
            AddOutputParam("圆面积度", "double", circleFinder.Result.CircleAreaRate);

            AddOutputParam("状态", "bool", ModuleParam.Status == eRunStatus.OK ? true : false);
            AddOutputParam("时间", "int", ModuleParam.ElapsedTime);
        }

        #endregion
    }
}
